package view;

import java.io.File;

import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

import model.MP3FileList;
import model.MP3FileMutableTreeNode;
import controller.TreeFileTreeSelectionListener;
import controller.XMLCache;

/**
 * DirectoryTree is a subclass of JTree.
 * Its constructor needs the gui as a parameter.
 * The data of the JTree is managed in a TreeModel. 
 *
 */
public class DirectoryTree extends JTree {

	private static final long serialVersionUID = 1L;
	private static DefaultTreeModel treeModel;

	public static DefaultTreeModel getTreeModel() {
		return treeModel;
	}

	public DirectoryTree(Object superview) {
		super();
		
		
		this.addDefaultNode();
		this.addTreeSelectionListener(new TreeFileTreeSelectionListener(this,superview));
	}

	// initialize the tree for the filesystem and a testenvironment
	private void addDefaultNode(){
		
		/*
		 * switch to testModel
		 */
		DefaultMutableTreeNode folder = new DefaultMutableTreeNode("Verzeichnis aussuchen");
		treeModel = new DefaultTreeModel(folder);
//		treeModel = new TestTreeModel();
		
		this.setModel(treeModel);
	}

	// initialize the tree for the filesystem and a testenvironment
	public void addNodesFromDirectory(String directoryString){
		DefaultMutableTreeNode rootDirectory = new DefaultMutableTreeNode(new MP3FileList(directoryString));
		rootDirectory.add(new DefaultMutableTreeNode("Verzeichnis aussuchen"));
		
		DirectoryTree.addAllChildren(directoryString, rootDirectory);							// listAllFiles...
		treeModel = new DefaultTreeModel(rootDirectory);	
		this.setModel(treeModel);
	}

	/*
	 * add recursively childrennodes to the parend node
	 */
	public static void addAllChildren(String directory, DefaultMutableTreeNode parent) {
		
		MP3FileList fileList = (MP3FileList) parent.getUserObject();
		File [] children = new File(directory).listFiles(); 
		
		/*
		 * check the cache first
		 */
		boolean hasToBeCached = XMLCache.hasToBeCached(directory);
		boolean successfullyCached = true;

		if(!hasToBeCached){
			System.out.println("reading from cache");

			fileList = XMLCache.readCache(directory);
			if(fileList == null) {
				fileList = (MP3FileList) parent.getUserObject();
//				XMLCache.deleteCache(directory);
				successfullyCached = false;
			}

			
			if (successfullyCached) {
				//first add mp3file node from cache
				for (MP3FileMutableTreeNode node : fileList.getFileList()) {
					parent.add(node);
				}
				//then continue recursively subdirectories
				for (int i = 0; i < children.length; i++) {
					//if the child is a directory
					if (children[i].isDirectory()
							&& !children[i].getName().startsWith(".")) {
						DefaultMutableTreeNode node = new DefaultMutableTreeNode(
								new MP3FileList(children[i].getName()));
						// recursive call to get subdirectories and files

						addAllChildren(children[i].getPath(), node);
						if (node.children().hasMoreElements()) {
							// add the found directory as a child node if it has at least one file in it
							parent.add(node);
						}
					}
				}
			}
		}
		if(hasToBeCached || !successfullyCached) {		
			 //list all the files in the selected directory
			for (int i = 0; i < children.length; i++) {
				//if the child is a directory
				if (children[i].isDirectory() && 
					!children[i].getName().startsWith(".")) { 
					DefaultMutableTreeNode node = new DefaultMutableTreeNode(new MP3FileList(children[i].getName()));
					// recursive call to get subdirectories and files
					
					addAllChildren(children[i].getPath(), node);
					if(node.children().hasMoreElements()){
						// add the found directory as a child node if it has at least one file in it
						parent.add(node);
					}
				} else 
				//if the child isn't a directory it has to be a mp3 file
				if (!children[i].isDirectory() && 
					!children[i].getName().startsWith(".") &&
					children[i].getName().toLowerCase().endsWith(".mp3")){
					MP3FileMutableTreeNode node = new MP3FileMutableTreeNode(children[i].getAbsolutePath(),
																			 children[i].getName().substring(0, children[i].getName().length()-4));
					//add the found mp3 file as a child node
					parent.add(node); 
					//add found mp3 to the fileList
					fileList.addFile(node);
				}
			}
			if(!fileList.getFileList().isEmpty()) {
				XMLCache.createCache(directory, fileList);
			}
		}
	}
	
}